package com.shu.consumer_producer;

import java.util.Queue;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @author ssm
 * @version V1.0
 * @description:
 * @date 2020/8/25 16:58
 */

public class ConditionTest {

    private Queue queue;
    private int max = 16;
    private ReentrantLock lock = new ReentrantLock();


    private Condition notEmpty = lock.newCondition();
    private Condition notFull = lock.newCondition();


    public ConditionTest(Queue queue, int max) {
        this.queue = queue;
        this.max = max;
    }


    public void put(Object o) throws InterruptedException {
        lock.lock();
        try {
            while (queue.size() == max) {
                notFull.await();
                System.out.println("激活put");
            }

            queue.add(o);

            notEmpty.signalAll();
        } finally {
            lock.unlock();
        }
    }


    public Object take() throws InterruptedException {
        lock.lock();
        try {
            while (queue.size() == 0) {
                notEmpty.await();
                System.out.println("激活take");
            }
            Object o = queue.remove();
            notFull.signalAll();
            return o;
        } finally {
            lock.unlock();
        }
    }


    public static void main(String[] args) throws InterruptedException {
        ConditionTest x = new ConditionTest(new ArrayBlockingQueue<>(1),1);

        Runnable producer = ()->{
            try {
                x.put(new Object());
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        };

        Runnable consumer = ()->{
            try {
                x.take();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        };

        new Thread(producer).start();
        new Thread(producer).start();

        new Thread(consumer).start();
        new Thread(consumer).start();

    }
}
